﻿package HTTP

import (
	"SQL/db"
	"logs"
	"net/http"
)

/*
URL: /addUser
/addUser? account=18826054758&nickname=newUser&iconurl=icon1&password=123456&customInfo={"sex":"male"}
{
	"Code":200,
	"Message":"",
	"Result":""
}*/
type result struct {
	UserID string
}

func AddUser(w http.ResponseWriter, req *http.Request) {
	code := Success
	msg := ""
	var obj interface{}
	err := req.ParseForm()
	if err != nil {
		logs.Print("req.ParseForm error", err.Error())
		code = errParseForm
		msg = err.Error()
		writeResult(w, code, msg, obj)
	}

	defer func() {
		writeResult(w, code, msg, obj)
	}()
	account := req.FormValue("account")
	if len(account) == 0 {
		msg = mInvalidEmptyArgs
		code = errInvalidEmptyArgs
		return
	}
	msg, code = checkerr("account", account)
	if code != Success {
		return
	}
	password := req.FormValue("password")
	if len(password) == 0 {
		msg = mInvalidEmptyArgs
		code = errInvalidEmptyArgs
		return
	}
	msg, code = checkerr("password", password)
	if code != Success {
		return
	}

	nickname := req.FormValue("nickname")
	if len(nickname) == 0 {
		msg = mInvalidNickname
		code = errInvalidNickname
		return
	}

	iconurl := req.FormValue("iconurl")
	if len(iconurl) == 0 {
		iconurl = "/img/icon/defaultIcon"
	}

	customInfo := req.FormValue("customInfo")
	var custom interface{}
	if len(customInfo) == 0 {
		custom = nil
	} else {
		msg, code = checkerr("customInfo", customInfo)
		if code != Success {
			return
		}
		custom = customInfo
	}
	code, msg, obj = AddUserToDB(password, account, nickname, iconurl, custom)
}

func AddUserToDB(password string, account string, nickname string, iconurl string, custom interface{}) (code int, msg string, Result interface{}) {
	//插入objects ->返回 id ->插入users ->完成
	DB, err := db.Getdb()
	if err != nil {
		code = errOpenDB
		msg = err.Error()
		return
	}

	tx, err := DB.Begin()
	if err != nil {
		code = errBeginTx
		msg = err.Error()
		return
	}

	defer func() {
		if code != Success {
			err := tx.Rollback()
			if err != nil {
				code = errEndTx
				msg = err.Error()
			}
		}
	}()

	var sql string
	var args []interface{}
	sql = "select * from users where account = $1"
	stmt, rows, err := db.TxQuery(tx, sql, account)
	defer stmt.Close()
	defer rows.Close()
	if err != nil {
		code = errDBQueryFailed
		msg = err.Error()
		return
	}
	if rows.Next() {
		code = errInvaildAccount
		msg = mExistsameAccount
		return
	}
	rows.Close()
	if custom != nil {
		sql = "insert into objects(nickname,iconurl,isUser,custom) values($1,$2,true,$3) returning id"
		args = append(args, nickname, iconurl, custom)
	} else {
		sql = "insert into objects(nickname,icon,isUser) values($1,$2,true) returning id"
		args = append(args, nickname, iconurl)
	}

	stmt, rows, err = db.TxQuery(tx, sql, args...)
	if err != nil {
		code = errDBQueryFailed
		msg = err.Error()
		return
	}
	var userID string
	if !rows.Next() {
		code = errDBQueryFailed
		msg = "no rows"
		return
	}
	err = rows.Scan(&userID)
	if err != nil {
		code = errRowsScan
		msg = err.Error()
		return
	}
	rows.Close()
	sql = "insert into users(id,account,password) values($1,$2,$3)"
	var objs []interface{}
	objs = append(objs, userID, account, password)
	err = db.TxExec(tx, sql, objs...)
	if err != nil {
		code = errDBExecFailed
		msg = err.Error()
		return
	}
	err = tx.Commit()
	if err != nil {
		code = errEndTx
		msg = err.Error()
		return
	}
	res := &result{UserID: userID}
	return Success, "", res
}
